package com.cheetah.start.common.config;

import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
import cn.dev33.satoken.interceptor.SaRouteInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.cheetah.start.common.config.property.UpLoadProprety;
import com.cheetah.start.common.constant.CommonConst;
import com.cheetah.start.common.interceptor.LoginInterceptor;
import com.cheetah.start.common.interceptor.UrlInterceptor;
import com.cheetah.start.common.plugin.repeat.impl.RepeatSubmitInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * web 配置
 *
 * @author Feel
 * @date 2021/6/11 18:11
 */
@Slf4j
@Configuration
public class ResourcesConfig implements WebMvcConfigurer {

    @Autowired
    private UpLoadProprety upLoadProprety;
    @Autowired
    private RepeatSubmitInterceptor repeatSubmitInterceptor;
    @Autowired
    private LoginInterceptor loginInterceptor;
    @Autowired
    private UrlInterceptor urlInterceptor;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(CommonConst.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + upLoadProprety.getPath() + "/");
    }


    /**
     * 拦截器注册
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
        // sa-token 拦截器
        registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
        registry.addInterceptor(new SaRouteInterceptor((req, res, handler) -> {
            SaRouter.match("/swagger-ui.html", r -> StpUtil.checkPermission("sys:swagger:main"));
            SaRouter.match("/koTime", r -> StpUtil.checkPermission("sys:kotime:main"));
        })).addPathPatterns("/swagger-ui.html").addPathPatterns("/koTime");
        registry.addInterceptor(urlInterceptor).addPathPatterns("/**").excludePathPatterns("/component/**");
    }

    /**
     * MessageConverter 处理返回的 json
     *
     * @param converters
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(
                // 保留 Map 空的字段
                SerializerFeature.WriteMapNullValue,
                // 将 String 类型的 null 转成""
                SerializerFeature.WriteNullStringAsEmpty,
                // 将 Number 类型的 null 转成 0
                SerializerFeature.WriteNullNumberAsZero,
                // 将 List 类型的 null 转成 []
                SerializerFeature.WriteNullListAsEmpty,
                // 将 Boolean 类型的 null 转成 false
                SerializerFeature.WriteNullBooleanAsFalse,
                // 使用日期格式化
                SerializerFeature.WriteDateUseDateFormat,
                // 避免循环引用
                SerializerFeature.DisableCircularReferenceDetect);

        converter.setFastJsonConfig(config);
        converter.setDefaultCharset(StandardCharsets.UTF_8);
        List<MediaType> mediaTypeList = new ArrayList<>();
        // 解决中文乱码问题，相当于在 Controller 上的 @RequestMapping 中加了个属性 produces = "application/json"
        mediaTypeList.add(MediaType.APPLICATION_JSON);
        converter.setSupportedMediaTypes(mediaTypeList);
        // 原先不生效
        // 解释 http://www.miss168.net/detail/science/631252567581528064/0/844370244045639680
        converters.add(0, converter);
    }

}
